Better implementation of native clear_area
authorAlexander Larsson <alexl@redhat.com>
Fri, 26 Jun 2009 15:07:24 +0000 (17:07 +0200)
committerAlexander Larsson <alexl@redhat.com>
Fri, 26 Jun 2009 15:07:24 +0000 (17:07 +0200)
Last commit was bad, as it didn't clip against client side
children. This implements such clipping first and then
only clears the rectangles that need to be cleared.

gdk/gdkwindow.c
gdk/gdkwindowimpl.h
gdk/x11/gdkwindow-x11.c

index 665e01f78df63d9e27c33fa41c804c3f6faf1f39..201f84af73bbb4025586a37faacd7b4fcabb3b6b 100644 (file)
@@ -4039,9 +4039,24 @@ gdk_window_clear_region_internal (GdkWindow *window,
       if (private->redirect)
        gdk_window_clear_backing_region_redirect (window, region);
 
-      gdk_window_clear_backing_region_direct (window, region);
-      if (send_expose)
-       gdk_window_invalidate_region (window, region, FALSE);
+      if (GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_region &&
+         gdk_window_has_impl (private))
+       {
+         GdkRegion *copy;
+         copy = gdk_region_copy (region);
+         gdk_region_intersect (copy, private->clip_region_with_children);
+
+         GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_region
+           (window, copy, send_expose);
+
+         gdk_region_destroy (copy);
+       }
+      else
+       {
+         gdk_window_clear_backing_region_direct (window, region);
+         if (send_expose)
+           gdk_window_invalidate_region (window, region, FALSE);
+       }
     }
 }
 
@@ -4062,13 +4077,6 @@ gdk_window_clear_area_internal (GdkWindow *window,
   if (GDK_WINDOW_DESTROYED (window))
     return;
 
-  if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
-    {
-      GDK_WINDOW_IMPL_GET_IFACE (private->impl)->clear_area
-       (window, x, y, width, height, send_expose);
-      return;
-    }
-
   /* This is what XClearArea does, and e.g. GtkCList uses it,
      so we need to duplicate that */
   if (width == 0)
index d12a872c5dd79991127c0a6ae8e121eaa0093415..ad1ae6b5e3045c7b85bb4a5c992ca3ddbcac7b3a 100644 (file)
@@ -71,11 +71,8 @@ struct _GdkWindowImplIface
                                          GdkWindow       *new_parent,
                                          gint             x,
                                          gint             y);
-  void         (* clear_area)           (GdkWindow       *window,
-                                         gint             x,
-                                         gint             y,
-                                        gint             width,
-                                        gint             height,
+  void         (* clear_region)         (GdkWindow       *window,
+                                        GdkRegion       *region,
                                         gboolean         send_expose);
   
   void         (* set_cursor)           (GdkWindow       *window,
index cd5a3778f655d6257eb38c4f6c2acc91cdf431e8..1c7c669e70a33f0e5127dcb86cfb9798b5b61f44 100644 (file)
@@ -1661,16 +1661,24 @@ gdk_window_x11_reparent (GdkWindow *window,
 }
 
 static void
-gdk_window_x11_clear_area (GdkWindow *window,
-                          gint       x,
-                          gint       y,
-                          gint       width,
-                          gint       height,
-                          gboolean   send_expose)
+gdk_window_x11_clear_region (GdkWindow *window,
+                            GdkRegion *region,
+                            gboolean   send_expose)
 {
-  XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
-             x, y, width, height,
-             send_expose);
+  GdkRectangle *rectangles;
+  int n_rectangles, i;
+
+  gdk_region_get_rectangles  (region,
+                             &rectangles,
+                             &n_rectangles);
+
+  for (i = 0; i < n_rectangles; i++)
+    XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
+               rectangles[i].x, rectangles[i].y,
+               rectangles[i].width, rectangles[i].height,
+               send_expose);
+
+  g_free (rectangles);
 }
 
 static void
@@ -5569,7 +5577,7 @@ gdk_window_impl_iface_init (GdkWindowImplIface *iface)
   iface->set_background = gdk_window_x11_set_background;
   iface->set_back_pixmap = gdk_window_x11_set_back_pixmap;
   iface->reparent = gdk_window_x11_reparent;
-  iface->clear_area = gdk_window_x11_clear_area;
+  iface->clear_region = gdk_window_x11_clear_region;
   iface->set_cursor = gdk_window_x11_set_cursor;
   iface->get_geometry = gdk_window_x11_get_geometry;
   iface->get_root_coords = gdk_window_x11_get_root_coords;